package dal;

import java.util.ArrayList;
import java.util.Collection;

import dal.datastore.Database;
import dal.datastore.PhysicalDataManipulation;
import dal.datastore.Table;
import dto.ColumnDTO;

/**
 * Database manipulations in here.
 * 
 * @author Stanley
 * 
 */
public class JMLDatabase {
	private PhysicalDataManipulation pdm;

	public JMLDatabase() {
		super();
		pdm = new PhysicalDataManipulation();
	}

	public boolean createDatabse(String dbname) throws Exception {
		if (!dbname.isEmpty()) {
			// 1. Create database
			Database db = new Database(dbname);
			// 2. add database to configuration file
			pdm.createDatabase(db);
			return true;

		} else {
			throw new Exception("Database name is null");
		}
	}

	/**
	 * Create table with table name
	 * 
	 * @param dbname
	 * @param tableName
	 * @return true if create succeed.
	 * @throws Exception
	 */
	public boolean createTable(String dbname, String tableName)
			throws Exception {
		if (dbname.isEmpty() || tableName.isEmpty()) {
			throw new Exception("Database name or table name is null");
		}
		return true;
	}

	/**
	 * Get all database name.
	 * 
	 * @return ArrayList
	 */
	public ArrayList<String> getAllDatabaseName() {
		Collection<Object> collection;
		try {
			collection = pdm.getAllDatabases();
		} catch (Exception e) {
			return null;
		}
		ArrayList<String> result = new ArrayList<String>();
		for (Object object : collection) {
			result.add(((Database) object).getName());
		}
		return result;
	}

	/**
	 * Drop a database
	 * 
	 * @param dbname
	 * @return true if drop successful and vice versa.
	 * @throws Exception
	 */
	public boolean dropDatabase(String dbname) throws Exception {
		if (!dbname.isEmpty()) {
			// 1. Create database
			Database db = new Database(dbname);
			// 2. add database to configuration file
			pdm.dropDatabase(db);
			return true;
		} else {
			throw new Exception("Database name is null");
		}
	}

	/**
	 * @param dbname
	 *            database name which is contains table.
	 * @param tableName
	 *            table name
	 * @param columns
	 *            a list of columns.
	 * @return true if create successful and vice versa.
	 * @throws Exception
	 */
	public boolean createTable(String dbname, String tableName,
			ArrayList<ColumnDTO> columns) throws Exception {
		if (dbname != null && tableName != null) {
			Table table = new Table(tableName, columns);
			ArrayList<Table> tables = new ArrayList<>();
			tables.add(table);
			Database db = new Database(dbname, tables);
			return pdm.updateDatabase(db);
		} else {
			throw new Exception("Table name or database name is invalid");
		}
	}

	/**
	 * Get all table name from database.
	 * 
	 * @param _databaseName
	 * @return ArrayList<String>
	 * @throws Exception
	 */
	public ArrayList<String> getAllTableName(String dbname) throws Exception {
		if (!dbname.isEmpty()) {
			// 1. Create database
			Database db = new Database(dbname);
			// 2. add database to configuration file

			Collection<Table> collection;
			try {
				collection = pdm.getAllTable(db);
			} catch (Exception e) {
				return null;
			}
			ArrayList<String> result = new ArrayList<String>();
			for (Object object : collection) {
				result.add(((Table) object).getName());
			}
			return result;
		} else {
			throw new Exception("Database name is null");
		}
	}

	
	/**
	 * Drop a table with dbname and table name
	 * @param dbname
	 * @param tableName 
	 * @return true if successful and vice versa.
	 * @throws Exception 
	 */
	public boolean dropTable(String dbname, String tableName) throws Exception {
		if (dbname == null || tableName == null) {
			throw new Exception("Database name or tablename is null");
		}
		// 1. Create database and table with name
		Database db = new Database(dbname);
		Table table = new Table(tableName);
		return pdm.dropTable(db, table);
	}
}
